package com.senseuni.da.ui

import android.annotation.SuppressLint
import android.content.Context
import android.net.wifi.ScanResult
import android.net.wifi.WifiInfo
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.annotation.NonNull
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.elvishew.xlog.XLog
import com.jeremyliao.liveeventbus.LiveEventBus
import com.seekwave.da.lib.wifi.WifiConnectorBuilder
import com.seekwave.da.lib.wifi.WifiUtils
import com.seekwave.da.lib.wifi.utils.SSIDUtils
import com.seekwave.da.lib.wifi.wifiConnect.ConnectionErrorCode
import com.seekwave.da.lib.wifi.wifiConnect.ConnectionSuccessListener
import com.seekwave.da.lib.wifi.wifiRemove.RemoveErrorCode
import com.seekwave.da.lib.wifi.wifiRemove.RemoveSuccessListener
import com.senseuni.da.R
import com.senseuni.da.adapter.WiFiScanResultAdapter
import com.senseuni.da.databinding.FragmentWifiSettingBinding
import com.senseuni.da.events.MyEvent
import com.senseuni.da.events.NetworkStateChangedEvent
import com.senseuni.da.ui.dialog.WifiConnectDialog
import com.senseuni.da.ui.dialog.WifiInfoDialog
import com.senseuni.da.utils.AppUtils
import com.senseuni.da.utils.showToast
import java.lang.ref.WeakReference


class WiFiSettingFragment : Fragment() {

    companion object {
        fun newInstance() = WiFiSettingFragment()

        const val MSG_START_SCAN = 0x11
    }

    private lateinit var viewModel: WiFiSettingViewModel
    private lateinit var binding: FragmentWifiSettingBinding

    private lateinit var mAdapter: WiFiScanResultAdapter

    private var mWifiUtilsBuilder: WifiConnectorBuilder.WifiUtilsBuilder? = null

    private lateinit var mHandler: UIHandler

    private var mConnectWifiSSID:String = ""

    private lateinit var applicationContext:Context

    private class UIHandler(fragment: WiFiSettingFragment) : Handler(Looper.getMainLooper()) {
        private val mOuter: WeakReference<WiFiSettingFragment> = WeakReference(fragment)
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            val fragment = mOuter.get()
            when (msg.what) {
                MSG_START_SCAN -> {
                    fragment?.startScan()
                }
            }
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentWifiSettingBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.viewWifiConnected.setOnClickListener {
            showWifiInfoDialog()
        }

        val layoutManager = LinearLayoutManager(context)
        binding.recyclerView.layoutManager = layoutManager


    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProvider(this).get(WiFiSettingViewModel::class.java)
        // TODO: Use the ViewModel

        applicationContext = context?.applicationContext!!

        mAdapter = WiFiScanResultAdapter(requireContext())
        binding.recyclerView.adapter = mAdapter

//        context?.registerReceiver(
//            broadcastReceiver,
//            IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
//        )

        mAdapter.setOnItemClickListener { item, position ->
            XLog.d("CLick wifi:${item.SSID}")
            val dialog = WifiConnectDialog(context)
            dialog.setTitle(getString(R.string.wifi_connect))
            dialog.setSsid(item.SSID)
            dialog.setOnResultListener { dialog, result ->
                XLog.d("connect wifi:${item.SSID},pwd:$result")
                dialog.dismiss()
                WifiUtils.withContext(applicationContext)
                    .connectWith(item.SSID, result)
                    .setTimeout(40000)
                    .onConnectionResult(object : ConnectionSuccessListener {
                        override fun success() {
                            XLog.d("connect wifi success:" + item.SSID)
                            Toast.makeText(applicationContext, "SUCCESS!", Toast.LENGTH_SHORT).show()

                            binding.groupWifiConnected.visibility = View.VISIBLE
                            mConnectWifiSSID = SSIDUtils.convertToQuotedString(item.SSID)
                            binding.viewWifiName.setTitle(item.SSID)
                            binding.viewWifiName.setSummary(R.string.connected)
                            binding.viewWifiSignal.setIconResource(AppUtils.getSignRes(context, item.level))
                            binding.viewWifiSignal.setSummary(AppUtils.getSignalDesc(context, item.level))
                        }

                        override fun failed(@NonNull errorCode: ConnectionErrorCode) {
                            XLog.d("connect wifi fail:" + item.SSID + ",errcode:" + errorCode.name)
                            String.format(getString(R.string.connect_fail), errorCode).showToast()
                        }
                    })
                    .start()
            }
            dialog.create().show()
        }

        mWifiUtilsBuilder = WifiUtils.withContext(context?.applicationContext!!)
        mWifiUtilsBuilder!!.enableWifi {
            if (it) {
                startScan()

                val wifiManager = context?.applicationContext!!.getSystemService(Context.WIFI_SERVICE) as android.net.wifi.WifiManager

                val wifiInfo = wifiManager.connectionInfo
                showCurrentWifi(wifiInfo)
            }
        }
        mHandler = UIHandler(this)

        listenWifi()
    }

    private fun startScan() {
        XLog.d("start scan wifi")
        mWifiUtilsBuilder?.scanWifi { list ->
            XLog.d("wifi scan result.size=" + list.size)
            val result = mutableListOf<ScanResult>()
            for (item in list) {
//                XLog.d("ssid:" + item.SSID + ",level:" + item.level + ",cap:" + item.capabilities)
                if (TextUtils.isEmpty(item.SSID)) {
                    continue
                }
                val ssid = SSIDUtils.convertToQuotedString(item.SSID)
                if (ssid == mConnectWifiSSID) {
                    continue
                }
//                result.add(item)
                mAdapter.addItem(item)
            }
//            mAdapter.setDataList(result)
            mHandler.sendEmptyMessageDelayed(MSG_START_SCAN, 10000)
        }?.start()
    }

    private fun listenWifi() {
        LiveEventBus.get(MyEvent.KEY_WIFI_STATE_CHANGED, Int::class.java)
            .observe(this) { t ->
                XLog.d("Wifi state change:$t")
            }

        LiveEventBus.get(MyEvent.KEY_NETWORK_STATE_CHANGED, NetworkStateChangedEvent::class.java)
            .observe(this
            ) { t ->
                t?.let {

                }
            }
    }

    private fun showCurrentWifi(wifiInfo : WifiInfo?) {
        val ret = wifiInfo?.let {
            XLog.d("found connect wifi:" + it.ssid + ",level:" + it.rssi)
            var result = true
            if ("0x" == it.ssid) {
                result = false
            } else {
                binding.groupWifiConnected.visibility = View.VISIBLE
                mConnectWifiSSID = SSIDUtils.convertToQuotedString(it.ssid)
                binding.viewWifiName.setTitle(it.ssid)
                binding.viewWifiName.setSummary(R.string.connected)
                binding.viewWifiSignal.setIconResource(AppUtils.getSignRes(context, it.rssi))
                binding.viewWifiSignal.setSummary(AppUtils.getSignalDesc(context, it.rssi))
            }
            result
        } ?: false
        if (!ret) {
            XLog.d("no connected wifi")
            binding.groupWifiConnected.visibility = View.GONE
        }
    }

    private fun showWifiInfoDialog() {
        val dialog = WifiInfoDialog(context)
        dialog.setTitle(getString(R.string.wifi_info))
        dialog.setOnResultListener { _dialog, result ->
            XLog.d("forget wifi:$result")
            _dialog.dismiss()
            WifiUtils.withContext(applicationContext)
                .remove(result, object : RemoveSuccessListener {
                    override fun success() {
                        XLog.d("remove wifi success:$result")
                        binding.groupWifiConnected.visibility = View.GONE
                    }

                    override fun failed(errorCode: RemoveErrorCode) {
                        XLog.d("remove wifi fail")
                    }
                })
        }
        dialog.create().show()
    }

//    private val broadcastReceiver = object : BroadcastReceiver() {
//        override fun onReceive(context: Context?, intent: Intent) {
//            val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)
//            Logger.d("WIFI SCAN Result:$success")
//            if (success) {
//                scanSuccess()
//            } else {
//                scanFailure()
//            }
//            //5s后再次扫描
//            mHandler.sendEmptyMessageDelayed(MSG_START_SCAN, 3000)
//        }
//    }

    @SuppressLint("MissingPermission")
    private fun scanSuccess() {
//        val results = mWifiManager.scanResults
//        for (result in results) {
//            Logger.d("WiFi Scan >> SSID: ${result.SSID}, BSSID: ${result.BSSID}, level:${result.level}, capabilities ${result.capabilities}")
//            if (result.SSID.isNotEmpty()) {
//                if (mConnectWifiSSID == result.SSID) continue
//                mAdapter.addItem(result)
//            }
//        }
    }

    private fun scanFailure() {
        XLog.e("wifi scan fail")
    }

    override fun onResume() {
        super.onResume()
        startScan()
    }

    override fun onPause() {
        super.onPause()
        mHandler.removeMessages(MSG_START_SCAN)
    }


    override fun onDestroy() {
        super.onDestroy()
        mHandler.removeMessages(MSG_START_SCAN)
//        mWifiManager.destroy()
//        context?.unregisterReceiver(broadcastReceiver)
//        mWifiManager.startScan()
    }

}